#include <stdio.h>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <fstream>
#include "SLIC.h"
#include <chrono>
#include <cstring>
#include <x86intrin.h>
#include <mpi.h>
#include <omp.h>
// #include <Eigen/Dense>
// #include "../avx_mathfun/avx_mathfun.h"
#include "utils.h"

typedef chrono::high_resolution_clock Clock;
#define __TEST__

int mpi_slave(){
    printf("MPI process number %d (on %d)\n", mrank, nprocs);
    int sz, all_width, all_height;
    int local_height;
    SLIC slic;
    MPI_Recv(&sz, 1, MPI_INT, 0, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&all_width, 1, MPI_INT, 0, 11, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&all_height, 1, MPI_INT, 0, 12, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    MPI_Recv(&local_height, 1, MPI_INT, 0, 13, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    int local_sz = local_height*all_width;
    printf("MPI process number %d (on %d) %d %d %d %d %d\n", mrank, nprocs, sz, all_width, all_height, local_height, local_sz);
    unsigned int* ubuff = align_new<unsigned int>(local_sz, 32);
    double* lvec = align_new<double>(local_sz, 32);
    double* avec = align_new<double>(local_sz, 32);
    double* bvec = align_new<double>(local_sz, 32);
    MPI_Request mrq[4];
    MPI_Recv(ubuff, local_sz, MPI_INT, 0, 1001, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    // MPI_Irecv(ubuff, local_sz, MPI_INT, 0, 1001,, MPI_COMM_WORLD, )
    slic.DoRGBtoLABConversion(ubuff, lvec, avec, bvec, all_width, local_height);
    MPI_Isend(lvec, local_sz, MPI_DOUBLE, 0, 1002, MPI_COMM_WORLD, &(mrq[1]));
    MPI_Isend(avec, local_sz, MPI_DOUBLE, 0, 1003, MPI_COMM_WORLD, &(mrq[2]));
    MPI_Isend(bvec, local_sz, MPI_DOUBLE, 0, 1004, MPI_COMM_WORLD, &(mrq[3]));
    return 0;
}